Hive中实现数据抽样的三种方法(数据块抽样、分桶抽样、随机抽样)使用与区别详解

您所在的位置:网站首页 sql 随机抽样 Hive中实现数据抽样的三种方法(数据块抽样、分桶抽样、随机抽样)使用与区别详解

Hive中实现数据抽样的三种方法(数据块抽样、分桶抽样、随机抽样)使用与区别详解

2024-02-25 03:15| 来源: 网络整理| 查看: 265

前言 当数据量特别大时,对全体数据进行处理存在困难时,抽样就显得尤其重要了。抽样可以从被抽取的数据中估计和推断出整体的特性,是科学实验、质量检验、社会调查普遍采用的一种经济有效的工作和研究方法。

Hive提供了数据取样(SAMPLING)的功能,能够根据一定的规则进行数据抽样,目前支持数据块抽样,分桶抽样和随机抽样,下面结合具体例子分别学习。

准备工作 (1)新建测试用表:employInfo

create table employInfo(deptID int,employID int,employName string,employSalary double) row format delimited fields terminated by ',';

(2)导入测试数据:

load data local inpath '/home/hadoop/datas/employInfo.txt' into table employinfo;

测试的数据量较小,只有100条数据: 在这里插入图片描述 下面分别介绍三种抽样方式:

一、数据块抽样(Block Sampling) 使用TABLESAMPLE函数抽取指定的 行数/比例/大小。

优点:速度快。 缺点:不随机,该方法实际上是按照文件中的顺序返回数据,对分区表从头开始抽取,可能造成只有前面几个分区的数据。如下:

1、 tablesample(n percent) 根据hive表数据的大小按比例抽取数据,并保存到新的hive表中。如:抽取原hive表中10%的数据。

注意:测试过程中发现,select语句不能带where条件且不支持子查询,可通过新建中间表或使用随机抽样解决该语句允许抽取数据大小的至少n%(不是行数,而是数据大小)做为输入,支持CombineHiveInputFormat而一些特殊的压缩格式是不能够被处理的,如果抽样失败,MapReduce作业的输入将是整个表。由于在HDFS块层级进行抽样,所以抽样粒度为块的大小,例如如果块大小为128MB,即使输入的n%仅为10MB,也会得到128MB的数据。

示例:

create table sample_table_percent as select * from employInfo tablesample(10 percent);

查看抽取的结果: 在这里插入图片描述 可见,虽然抽取的是10%,但是返回了所有行的数据(因为测试数据总量太小就一个Block,所以全部返回了)。

2、tablesample(n M) 指定抽样数据的大小,单位为M。

3、tablesample(n rows) 指定抽样数据的行数,其中n代表每个map任务均取n行数据,map数量可通过hive表的简单查询语句确认(关键词:number of mappers: x) 示例:

create table sample_table_ROWS as select * from employInfo TABLESAMPLE (10 ROWS);

查看抽取的结果: 在这里插入图片描述 如上图所示,因为就只有一个map,所以只抽取了10行数据。

二、分桶抽样(Smapling Bucketized Table) hive中分桶其实就是根据某一个字段Hash取模,放入指定数据的桶中,比如将表table_1按照ID分成100个桶,其算法是hash(id) % 100,这样,hash(id) % 100 = 0的数据被放到第一个桶中,hash(id) % 100 = 1的记录被放到第二个桶中。创建分桶表的关键语句为:CLUSTER BY语句。

优点:随机,测试发现,速度比方法3的rand()快。

分桶抽样语法: TABLESAMPLE (BUCKET x OUT OF y [ON colname]) 其中x是要抽样的桶编号,桶编号从1开始,colname表示抽样的列,y表示桶的数量。

示例,将表中数据随机分到10个桶,抽取第一个桶的数据,如下:

create table sample_table_bucket2 as select * from employInfo TABLESAMPLE (BUCKET 1 OUT OF 10 ON rand());

在这里插入图片描述 示例,将表中数据按照部门编号分到3个桶,并抽取第一个桶的数据,如下:

create table sample_table_bucket4 as select * from employInfo TABLESAMPLE (BUCKET 1 OUT OF 3 ON deptID);

在这里插入图片描述 可见,有两个部门都被分配到了第一个桶。

三、随机抽样(rand()函数)

1、方式一:使用order by 此时,可以提供真正的随机抽样,但是需要在单个 reducer 中进行总排序(https://blog.csdn.net/weixin_43230682/article/details/107342575Hive中的四种排序方式(order by,sort by,distribute by,cluster by)使用与区别详解 一文中有具体介绍),速度慢。 示例:

create table sample_table_order as select * from employInfo ORDER BY rand() limit 10;

查看抽取的结果: 在这里插入图片描述 经测试对比,千万级数据中进行随机抽样 order by方式耗时更长,大约多30秒左右。

2、方式二:使用sort by Hive 提供了 sort by,sort by 提供了单个 reducer 内的排序功能,但不保证整体有序,所以下面的语句是不保证随机性的:

create table sample_table_sort as select * from employInfo SORT BY rand() limit 10;

3、方式三:使用distribute by和sort by 使用rand()函数进行随机抽样,limit关键字限制抽样返回的数据,其中rand函数前的distribute和sort关键字可以保证数据在mapper和reducer阶段是随机分布的,例如:

create table sample_table_distribute as select * from employInfo where rand()


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3